package com.cata.mall.controller;

import cn.hutool.core.collection.CollUtil;
import com.cata.mall.common.api.CommonPage;
import com.cata.mall.common.api.CommonResult;
import com.cata.mall.dto.UmsAdminLoginParam;
import com.cata.mall.dto.UmsAdminParam;
import com.cata.mall.dto.UpdateAdminPasswordParam;
import com.cata.mall.model.UmsAdmin;
import com.cata.mall.model.UmsRole;
import com.cata.mall.service.UmsAdminService;
import com.cata.mall.service.UmsRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @作者: Tao
 * @日期: 2025/10/14
 * @时间: 10:22
 * @描述: 后台用户管理Controller<pre>
 */
@RestController
@Api(tags = "UmsAdminController")
@Tag(name = "UmsAdminController", description = "后台用户管理")
@RequestMapping("/admin")
public class UmsAdminController {
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private UmsRoleService roleService;

    /**
     * 用户注册接口
     *
     * @param umsAdminParam 用户注册参数，包含用户名、密码等信息
     * @return 注册成功返回用户信息，注册失败返回错误信息
     */
    @ApiOperation(value = "用户注册")
    @PostMapping("/register")
    public CommonResult<UmsAdmin> register(@Validated @RequestBody UmsAdminParam umsAdminParam) {
        // 调用服务层进行用户注册
        UmsAdmin umsAdmin = adminService.register(umsAdminParam);
        if (umsAdmin == null) {
            // 注册失败，返回失败结果
            return CommonResult.failed();
        }
        // 注册成功，返回成功结果和用户信息
        return CommonResult.success(umsAdmin);
    }

    /**
     * 用户登录接口，验证用户身份并返回JWT token
     *
     * @param umsAdminLoginParam 登录参数对象，包含用户名和密码，必须通过验证
     * @return CommonResult 包含登录结果的对象：
     * - 登录成功：数据为包含token和tokenHead的Map
     * - 登录失败：提示"用户名或密码错误"
     */
    @ApiOperation(value = "登录以后返回token")
    @PostMapping(value = "/login")
    public CommonResult login(@Validated @RequestBody UmsAdminLoginParam umsAdminLoginParam) {
        // 调用服务层进行登录验证，获取JWT token
        String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword());

        // 验证登录结果，如果token为空表示用户名或密码错误
        if (token == null) {
            return CommonResult.validateFailed("用户名或密码错误");
        }

        // 构造返回数据，包含token和token头部标识
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return CommonResult.success(tokenMap);
    }

    /**
     * 获取当前登录用户信息
     *
     * @param principal 当前认证用户信息
     * @return 包含用户信息、菜单列表、角色信息等的通用返回结果
     */
    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping(value = "/info")
    public CommonResult getAdminInfo(Principal principal) {
        // 检查用户是否已认证
        if (principal == null) {
            return CommonResult.unauthorized(null);
        }
        String username = principal.getName();
        UmsAdmin umsAdmin = adminService.getAdminByUsername(username);

        // 构建返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("username", umsAdmin.getUsername());
        data.put("menus", roleService.getMenuList(umsAdmin.getId()));
        data.put("icon", umsAdmin.getIcon());

        // 获取并处理用户角色信息
        List<UmsRole> roleList = adminService.getRoleList(umsAdmin.getId());
        if (CollUtil.isNotEmpty(roleList)) {
            List<String> roles = roleList.stream().map(UmsRole::getName).collect(Collectors.toList());
            data.put("roles", roles);
        }
        return CommonResult.success(data);
    }

    /**
     * 用户登出功能
     * 该方法处理用户登出请求，通过调用adminService的logout方法来执行具体的登出逻辑
     *
     * @param principal 包含当前认证用户信息的对象，用于获取用户名
     * @return CommonResult 登出操作的结果，成功时返回null数据
     */
    @ApiOperation(value = "登出功能")
    @PostMapping(value = "/logout")
    public CommonResult logout(Principal principal) {
        // 获取当前登录用户的用户名
        String username = principal.getName();
        // 调用服务层执行登出操作
        adminService.logout(username);
        return CommonResult.success(null);
    }

    /**
     * 根据用户名或姓名分页获取用户列表
     * @param keyword 搜索关键字，用于匹配用户名或姓名
     * @param pageSize 每页显示记录数，默认值为5
     * @param pageNum 页码，默认值为1
     * @return 包含分页用户信息的通用返回结果
     */
    @ApiOperation("根据用户名或姓名分页获取用户列表")
    @GetMapping(value = "/list")
    public CommonResult<CommonPage<UmsAdmin>> list(@RequestParam(value = "keyword", required = false) String keyword,
                                                   @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                                                   @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        List<UmsAdmin> list = adminService.list(keyword, pageSize, pageNum);
        return CommonResult.success(CommonPage.restPage(list));
    }

    /**
     * 获取指定用户信息
     * @param id 用户ID
     * @return 返回指定用户的详细信息
     */
    @ApiOperation("获取指定用户信息")
    @GetMapping(value = "/{id}")
    public CommonResult<UmsAdmin> getItem(@PathVariable Long id) {
        // 调用服务层获取用户信息
        UmsAdmin admin = adminService.getItem(id);
        // 封装成功响应结果
        return CommonResult.success(admin);
    }

    /**
     * 修改指定用户信息
     * @param id 用户ID
     * @param admin 用户信息对象
     * @return CommonResult 返回操作结果，成功时返回影响记录数，失败时返回错误信息
     */
    @ApiOperation("修改指定用户信息")
    @PostMapping(value = "/update/{id}")
    public CommonResult update(@PathVariable Long id, @RequestBody UmsAdmin admin) {
        // 调用服务层更新用户信息
        int count = adminService.update(id, admin);
        // 根据更新结果返回相应响应
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    /**
     * 修改指定用户密码
     * @param updatePasswordParam 包含用户ID、旧密码和新密码的参数对象，必须通过验证
     * @return CommonResult 返回操作结果：<pre>
     *         - 成功时返回状态码大于0<pre>
     *         - 参数不合法时返回-1<pre>
     *         - 用户不存在时返回-2<pre>
     *         - 旧密码错误时返回-3<pre>
     *         - 其他错误情况返回失败结果
     */
    @ApiOperation("修改指定用户密码")
    @PostMapping(value = "/updatePassword")
    public CommonResult updatePassword(@Validated @RequestBody UpdateAdminPasswordParam updatePasswordParam) {
        int status = adminService.updatePassword(updatePasswordParam);
        // 根据服务层返回的状态码判断操作结果并返回相应信息
        if (status > 0) {
            return CommonResult.success(status);
        } else if (status == -1) {
            return CommonResult.failed("提交参数不合法");
        } else if (status == -2) {
            return CommonResult.failed("找不到该用户");
        } else if (status == -3) {
            return CommonResult.failed("旧密码错误");
        } else {
            return CommonResult.failed();
        }
    }

    /**
     * 删除指定用户信息
     * @param id 用户ID
     * @return 删除结果，成功返回删除数量，失败返回错误信息
     */
    @ApiOperation("删除指定用户信息")
    @PostMapping(value = "/delete/{id}")
    public CommonResult delete(@PathVariable Long id) {
        // 执行删除操作并根据结果返回相应信息
        int count = adminService.delete(id);
        return count > 0 ? CommonResult.success(count) : CommonResult.failed();
    }

    /**
     * 修改帐号状态
     * @param id 帐号ID
     * @param status 帐号状态值
     * @return 操作结果，成功时返回影响记录数，失败时返回错误信息
     */
    @ApiOperation("修改帐号状态")
    @PostMapping(value = "/updateStatus/{id}")
    public CommonResult updateStatus(@PathVariable Long id,@RequestParam(value = "status") Integer status) {
        // 创建管理员对象并设置状态
        UmsAdmin admin = new UmsAdmin();
        admin.setStatus(status);
        // 执行更新操作
        int count = adminService.update(id,admin);
        // 根据更新结果返回相应信息
        if (count > 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    /**
     * 给用户分配角色
     * @param adminId 用户ID
     * @param roleIds 角色ID列表
     * @return 操作结果，成功时返回影响的记录数，失败时返回错误信息
     */
    @ApiOperation("给用户分配角色")
    @PostMapping(value = "/role/update")
    public CommonResult updateRole(@RequestParam("adminId") Long adminId,
                                   @RequestParam("roleIds") List<Long> roleIds) {
        // 调用服务层更新用户角色关联关系
        int count = adminService.updateRole(adminId, roleIds);
        // 根据更新结果返回相应的响应
        if (count >= 0) {
            return CommonResult.success(count);
        }
        return CommonResult.failed();
    }

    @ApiOperation("获取指定用户的角色")
    @GetMapping(value = "/role/{adminId}")
    public CommonResult<List<UmsRole>> getRoleList(@PathVariable Long adminId) {
        List<UmsRole> roleList = adminService.getRoleList(adminId);
        return CommonResult.success(roleList);
    }

}
